require 'digest/sha2'
class User < ActiveRecord::Base
  has_many :posts, :dependent => :nullify
  has_many :topics, :through => :posts
  has_many :moderatorships, :dependent => :destroy
  has_many :moderated_forums, :through => :moderatorships, :source => :forum
  has_many :reports
  has_many :subscriptions, :dependent => :destroy
  
  validates_presence_of     :name
  validates_uniqueness_of   :name
  validates_length_of				:name, :maximum => 15
#  validates_format_of				:name, :with => /^[\w\d_-]*$/
  validates_format_of       :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
  validates_presence_of     :password, :on => :create
  validates_confirmation_of :password
  validates_length_of       :password, :minimum => 4, :on => :create

  
  before_create :prepare_password
  before_create { |u| u.kind = 'Admin' if User.find_by_kind('Admin').nil? }
  before_save { |u| u.last_session_at = Time.now if u.last_session_at.nil? }
  
  attr_accessor :password
  
  include PermissionHandler
  
  def last_post # REFACTORME duplicate with topic and forum models
    posts.find(:first, :order => 'created_at DESC')
  end
  
  def correct_password?(pass)
    encrypt_password(pass) == password_hash
  end

  def reset_login_token!
    self.login_token = Digest::MD5.hexdigest((rand(9*9*9)+1).to_s)
    save!
    login_token
  end
  
  def seen_now!
  	self.last_session_at = self.last_seen_at if !self.last_seen_at.nil? && self.last_seen_at < 30.minutes.ago 
    self.last_seen_at = Time.now
    save!
  end
  
  def online?
    (last_seen_at || created_at) > Time.now.utc-10.minutes
  end
  
  def admin?; false; end
  
  def guest?; false; end
  
  def banned?; false; end
  
  def moderated_by?(user); false; end
  
  def owned_by?(user)
    self == user
  end
  
  def subscribed_to?(topic)
    Subscription.count(:conditions => ["topic_id = ? AND user_id = ?", topic.id, self.id]) > 0
  end
  
  def find_subscription(topic)
    Subscription.find(:first, :conditions => ["topic_id = ? AND user_id = ?", topic.id, self.id])
  end
  
  def validate
    unless signature.blank?
      errors.add :signature, 'must be three lines or less' if signature.to_a.length > 3
      errors.add :signature, 'line must be 50 characters or less' if signature.to_a.collect(&:length).max > 50
    end
    unless date_of_birth.nil?
      errors.add :date_of_birth, 'must be more than 13 years ago' if date_of_birth.to_time > 13.years.ago
    end
  end
  
  class << self
    def kinds
      ['Member', 'Admin', 'Banned'] # TODO This will need to be dynamic
    end
    
    def authenticate(name, pass)
      user = User.find_by_name(name)
      if user && user.correct_password?(pass)
        user
      else
        nil
      end
    end
    
    def inheritance_column
      'kind'
    end
    
    def currently_online
      find :all, :conditions => ['last_seen_at > ?', Time.now-10.minutes]
    end
  end
  
  private
  
  def prepare_password
    self.password_salt = String.random_string
    self.password_hash = encrypt_password(@password)
  end
  
  def encrypt_password(pass)
    Digest::SHA256.hexdigest(pass + password_salt)
  end
  
end
